﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using LDSBusiness;
using LDSBusiness.EventArgs;
using LDSCore;
using LDSModel;
using LDSModel.Dal;
using LDSModel.Item;
using LDSProject.Properties;
using Newtonsoft.Json;

namespace LDSProject
{
    internal class MainConsole
    {
        static readonly object ObjLock = new object();
        static readonly object ObjLockdeviceState = new object();

        MainForm _form;
        int _syncTimeType;
        public DateTime NextSyncTime;
        System.Windows.Forms.Timer _syncTimer;
        public List<ErrInfoItem> ErrorInfoList;

        #region 界面

        /// <summary>
        /// 油罐位置
        /// </summary>
        public Dictionary<Guid, Point> OilTankPostion;

        /// <summary>
        /// 设备位置
        /// </summary>
        public readonly Dictionary<int, Point> DevicePostion;

        #endregion

        #region 设备状态监测

        readonly Dictionary<Guid, DateTime> _deviceOnlineTimeList;
        public Dictionary<Guid, DateTime> DeviceAlermTimeList;
        readonly Dictionary<Guid, DeviceState> _deviceStateList;
        readonly Dictionary<Guid, DeviceState> _oilTankStateList;
        readonly Dictionary<Guid, int> _oilTankOnlineCountList;

        /// <summary>
        /// 设备状态监测线程
        /// </summary>
        bool _exitStateCheckThread;

        /// <summary>
        /// 解析数据线程
        /// </summary>
        bool _exitLoseDataThread;

        /// <summary>
        /// 设备离线询问线程
        /// </summary>
        bool _exitOfflineCheckThread;

        #endregion

        /// <summary>
        /// 设备状态改变事件
        /// </summary>
        public event DelegateDeviceStateChanged OnDeviceStateChanged;

        /// <summary>
        /// 油罐状态改变事件
        /// </summary>
        public event DelegateOilTankStateChanged OnOilTankStateChanged;

        /// <summary>
        /// 雷电流幅值数据接收事件
        /// </summary>
        public event DelegateRecordReceived OnRecordReceived;

        public event DelegateEmpty OnPortStop;

        public MainConsole()
        {
            OilTankPostion = new Dictionary<Guid, Point>();

            DevicePostion = new Dictionary<int, Point>
                {
                    {1, new Point(274, 218)},
                    {2, new Point(404, 91)},
                    {3, new Point(555, 213)},
                    {4, new Point(317, 320)},
                    {5, new Point(579, 388)},
                    {6, new Point(135, 371)}
                };

            _deviceOnlineTimeList = new Dictionary<Guid, DateTime>();
            DeviceAlermTimeList = new Dictionary<Guid, DateTime>();
            _deviceStateList = new Dictionary<Guid, DeviceState>();
            _oilTankStateList = new Dictionary<Guid, DeviceState>();
            _oilTankOnlineCountList = new Dictionary<Guid, int>();
            ErrorInfoList = new List<ErrInfoItem>();

            DataRecipient.Instance.OnMsgProcess += Instance_OnMsgProcess;
            OnRecordReceived += MainConsole_OnRecordReceived;
        }

        internal void Init(MainForm form)
        {
            try
            {
                _form = form;

                var type = Settings.Default.SyncTimeType;
                SetNextSyncTime(type);
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex);
            }
        }

        internal void SetNextSyncTime(int type)
        {
            if (null != _syncTimer)
            {
                _syncTimer.Stop();
                _syncTimer = null;
            }

            _syncTimer = new System.Windows.Forms.Timer();
            _syncTimer.Tick += syncTimer_Tick;

            _syncTimeType = type;

            switch (_syncTimeType)
            {
                case 1:
                    {
                        NextSyncTime = DateTime.Now.AddDays(1);
                        _syncTimer.Interval = (int)TimeSpan.FromDays(1).TotalMilliseconds;
                    }
                    break;
                case 2:
                    {
                        NextSyncTime = DateTime.Now.AddDays(7);
                        _syncTimer.Interval = (int)TimeSpan.FromDays(7).TotalMilliseconds;
                    }
                    break;
                default:
                    {
                        NextSyncTime = DateTime.Now.AddHours(1);
                        _syncTimer.Interval = (int)TimeSpan.FromHours(1).TotalMilliseconds;
                        _syncTimeType = 0;
                    }
                    break;
            }

            _syncTimer.Start();
        }

        void syncTimer_Tick(object sender, EventArgs e)
        {
            switch (_syncTimeType)
            {
                case 1:
                    {
                        NextSyncTime = DateTime.Now.AddDays(1);
                    }
                    break;
                case 2:
                    {
                        NextSyncTime = DateTime.Now.AddDays(7);
                    }
                    break;
                default:
                    {
                        NextSyncTime = DateTime.Now.AddHours(1);
                    }
                    break;
            }
            ThreadExecutor.Execute(syncTimerHandler);
        }

        static void syncTimerHandler(object state)
        {
            foreach (var device in DeviceService.Instance.DeviceList)
            {
                if (device.Address != null) DataSender.Instance.SetSysTime(device.Address.Value);
#if _TRACE
                Console.WriteLine(string.Format("自动同步时间： 线程Id({0}),发送地址({1})),时间({2})", Thread.CurrentThread.ManagedThreadId, device.Address, DateTime.Now));
#endif
                Thread.Sleep(5000);
            }
        }

        public bool Start(IWin32Window sender)
        {
            var serialPort = new SerialPort(Settings.Default.PortName)
                {
                    BaudRate = Settings.Default.PortBaudRate
                };

            var result = DataRecipient.Instance.Start(serialPort);

            if (result.Success)
            {
                ThreadExecutor.Execute(CheckStateHandler);
                ThreadExecutor.Execute(StateCheckHandler);
                ThreadExecutor.Execute(OfflineCheckHandler);
                ThreadExecutor.Execute(LoseDataHandler);

                return true;
            }
            MessageBox.Show(sender, result.Exception.Message, @"错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return false;
        }

        public void Stop()
        {
            try
            {
                _exitStateCheckThread = true;
                _exitOfflineCheckThread = true;
                _exitLoseDataThread = true;

                DataRecipient.Instance.Stop();
                _deviceOnlineTimeList.Clear();
                DeviceAlermTimeList.Clear();
                _deviceStateList.Clear();
                _oilTankStateList.Clear();
                _oilTankOnlineCountList.Clear();

                if (OnPortStop != null)
                    OnPortStop();
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex);
            }
            finally
            {
                GC.Collect();
            }
        }

        static void CheckStateHandler(object state)
        {
            Thread.Sleep(1000);

            foreach (var device in DeviceService.Instance.DeviceList)
            {
                if (device.Address != null) DataSender.Instance.CheckState(device.Address.Value);
                Thread.Sleep(300);
            }
        }

        void OfflineCheckHandler(object state)
        {
            while (true)
            {
                Thread.Sleep(10000);

                if (_exitOfflineCheckThread)
                {
                    _exitOfflineCheckThread = false;
                    return;
                }

                try
                {
                    Dictionary<Guid, DeviceState> deviceList;
                    lock (ObjLockdeviceState)
                    {
                        deviceList = new Dictionary<Guid, DeviceState>(_deviceStateList);
                    }

                    foreach (var device in from dev in deviceList where dev.Value == DeviceState.Offline select (from d in DeviceService.Instance.DeviceList where d.DeviceId == dev.Key select d).FirstOrDefault())
                    {
                        if (device != null)
                            if (device.Address != null) DataSender.Instance.CheckState(device.Address.Value);
                        Thread.Sleep(5000);
                    }
                }
                catch (Exception ex)
                {
                    LogFileHelper.Record(ex);
                }
            }
        }

        /// <summary>
        /// 设备状态监测线程
        /// </summary>
        void StateCheckHandler(object state)
        {
            while (true)
            {
                if (_exitStateCheckThread)
                {
                    _exitStateCheckThread = false;
                    return;
                }

                try
                {
                    foreach (var device in DeviceService.Instance.DeviceList)
                    {
                        DeviceState oldState;
                        DeviceState curState;
                        GetDeviceState(device.DeviceId, out oldState, out curState);

                        if (curState == oldState) continue;
                        if (curState == DeviceState.Offline)                                   // 下线
                        {
                            for (var i = 0; i < 2; ++i)
                            {
                                if (device.Address != null) DataSender.Instance.CheckState(device.Address.Value);
                                Thread.Sleep(5000);
                                GetDeviceState(device.DeviceId, out oldState, out curState);
                                if (curState != DeviceState.Offline) break;
                            }

                            if (curState == DeviceState.Offline)
                            {
                                CheckDeviceState(device.DeviceId, OnDeviceStateChanged, OnOilTankStateChanged);
                            }

                            //int count = 0;
                            //deviceOfflineCountList.TryGetValue(device.DeviceId, out count);
                            //deviceOfflineCountList.Remove(device.DeviceId);
                            //if (count < 2)
                            //{
                            //    deviceOfflineCountList.Add(device.DeviceId, count + 1);
                            //    if (deviceOnlineTimeList.ContainsKey(device.DeviceId))
                            //    {
                            //        deviceOnlineTimeList.Remove(device.DeviceId);
                            //    }
                            //    deviceOnlineTimeList.Add(device.DeviceId, DateTime.Now);
                            //    continue;
                            //}
                            //else
                            //{
                            //    // 发数据
                            //    // 等待回传
                            //    // 如果没有回传才执行下面这句
                            //    DataSender.Instance.CheckState(device.Address.Value);
                            //    Thread.Sleep(5000);
                            //    GetDeviceState(device.DeviceId, out oldState, out state);
                            //    if (state == DeviceState.Offline)
                            //    {
                            //        CheckDeviceState(device.DeviceId, OnDeviceStateChanged, OnOilTankStateChanged);
                            //    }
                            //}
                        }
                        else
                        {
                            CheckDeviceState(device.DeviceId, OnDeviceStateChanged, OnOilTankStateChanged);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogFileHelper.Record(ex);
                }

                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 设备状态改变分发
        /// </summary>
        /// <param name="deviceId">设备Id</param>
        /// <param name="onDeviceStateChanged">设备在线状态改变事件</param>
        /// <param name="onOilTankStateChanged">油罐状态改变事件</param>
        public void CheckDeviceState(Guid deviceId, DelegateDeviceStateChanged onDeviceStateChanged, DelegateOilTankStateChanged onOilTankStateChanged)
        {
            try
            {
                DeviceState oldState;
                DeviceState state;
                GetDeviceState(deviceId, out oldState, out state);

                lock (ObjLockdeviceState)
                {
                    if (_deviceStateList.ContainsKey(deviceId))
                    {
                        _deviceStateList.Remove(deviceId);
                    }
                    _deviceStateList.Add(deviceId, state);
                }

                if (null != onDeviceStateChanged)
                {
                    onDeviceStateChanged(this, new DeviceStateChangedEventArgs(deviceId, state));
                }

                if (null == onOilTankStateChanged) return;
                var oilTank = DeviceService.Instance.GetOilTankByDeviceId(deviceId);
                if (null == oilTank) return;
                int onlineDeviceCount;
                _oilTankOnlineCountList.TryGetValue(oilTank.OId, out onlineDeviceCount);

                if (oldState == DeviceState.Offline && state == DeviceState.Online)
                {
                    onlineDeviceCount++;
                }
                else if (oldState == DeviceState.Online && state == DeviceState.Offline)
                {
                    onlineDeviceCount--;
                }

                if (_oilTankOnlineCountList.ContainsKey(oilTank.OId))
                {
                    _oilTankOnlineCountList.Remove(oilTank.OId);
                }
                _oilTankOnlineCountList.Add(oilTank.OId, onlineDeviceCount);

                onOilTankStateChanged(this, new OilTankStateChangedEventArgs(oilTank.OId, onlineDeviceCount, state));
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex);
            }
        }

        /// <summary>
        /// 得到设备状态（包括上一个状态和当前状态）
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="oldState"></param>
        /// <param name="state"></param>
        private void GetDeviceState(Guid deviceId, out DeviceState oldState, out DeviceState state)
        {
            oldState = DeviceState.Offline;
            state = DeviceState.Offline;
            try
            {
                lock (ObjLockdeviceState)
                {
                    _deviceStateList.TryGetValue(deviceId, out oldState);
                }

                DateTime onlineTime;
                _deviceOnlineTimeList.TryGetValue(deviceId, out onlineTime);
                if (DateTime.Now.Subtract(onlineTime).TotalSeconds < Settings.Default.OnlineTimeOut)
                    state = DeviceState.Online;

                DateTime alarmTime;
                DeviceAlermTimeList.TryGetValue(deviceId, out alarmTime);
                if (DateTime.Now.Subtract(alarmTime).TotalSeconds < Settings.Default.AlermTimeOut)
                    state = DeviceState.Alarm;
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex);
            }
        }

        /// <summary>
        /// 获取丢失数据处理线程
        /// </summary>
        void LoseDataHandler(object state)
        {
            while (true)
            {
                if (_exitLoseDataThread)
                {
                    _exitLoseDataThread = false;
                    return;
                }

                try
                {
                    Dictionary<Guid, DeviceState> deviceList;
                    lock (ObjLockdeviceState)
                    {
                        deviceList = new Dictionary<Guid, DeviceState>(_deviceStateList);
                    }

                    foreach (var dic in deviceList)
                    {
                        if (dic.Value == DeviceState.Offline) continue;

                        var loseData = DeviceService.Instance.GetLostRecord(dic.Key, 100);

                        if (loseData != null && loseData.Any())
                        {
                            var device = DeviceService.Instance.GetDevice(dic.Key);

                            foreach (var index in loseData)
                            {
#if _TRACE
                                Console.WriteLine(string.Format("自动获取数据: 线程Id({0}),发送地址({1}),数据({2}),时间({3})", Thread.CurrentThread.ManagedThreadId, device.Address.Value, index, DateTime.Now));
#endif
                                if (device.Address != null) DataSender.Instance.ReadRecord(device.Address.Value, index);
                                Thread.Sleep(5000);
                            }
                        }
                        Thread.Sleep(2000);
                    }
                }
                catch (Exception ex)
                {
                    LogFileHelper.Record(ex);
                }
                // 休眠10分钟
                Thread.Sleep(600 * 1000);
            }
        }

        /// <summary>
        /// 记录保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        static void MainConsole_OnRecordReceived(object sender, RecordReceivedEventArgs args)
        {
            try
            {
                var context = new DatabaseEntities();

#if _TRACE
                Console.WriteLine(string.Format("保存数据: 线程Id({0}),发送地址({1}),数据({2}),时间({3})", Thread.CurrentThread.ManagedThreadId, DeviceService.Instance.GetDevice(args.Record.DeviceID).Address, JsonConvert.SerializeObject(args.Record), DateTime.Now));
#endif

                context.AddToData_Records(args.Record);
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex, "数据：" + JsonConvert.SerializeObject(args.Record));

                args.Record.AlarmTime = DateTime.Now;

                try
                {
                    var context = new DatabaseEntities();
                    context.AddToData_Records(args.Record);
                    context.SaveChanges();

                    // 同步设备时间
                    var address = DeviceService.Instance.GetDevice(args.Record.DeviceID).Address;
                    if (address != null)
                        DataSender.Instance.SetSysTime(address.Value);
                }
                catch (Exception err)
                {
                    LogFileHelper.Record(err, "修正保存数据失败，数据：" + JsonConvert.SerializeObject(args.Record));
                }
            }
        }

        void Instance_OnMsgProcess(object sender, MsgProcessEventArgs args)
        {
            var msg = args.Msg;
            RecordItem data = null;

            try
            {

#if _TRACE
                Console.WriteLine(string.Format("消息处理： 线程Id({0}),发送地址({1}),数据({2}),时间({3})", Thread.CurrentThread.ManagedThreadId, msg.SrcAddr, JsonConvert.SerializeObject(msg), DateTime.Now));
#endif

                var device = DeviceService.Instance.GetDevice(msg.SrcAddr);

                if (device == null) return;
                switch ((MsgType)msg.MsgType)
                {
                    #region 接收一条记录
                    case MsgType.ZGCMD_SEND_RECORD:
                        {
                            DataSender.Instance.Answer(msg, true);

                            data = new RecordItem().FromBytes(msg.Buffer);

                            var record = new Data_Records
                                {
                                    RecordId = Guid.NewGuid(),
                                    CH1Value = Convert.ToDecimal(data.Ch1Value),
                                    CH2Value = Convert.ToDecimal(data.Ch2Value),
                                    AlarmTime = data.AlarmTime,
                                    AlarmCount = data.AlarmCount,
                                    DeviceID = device.DeviceId
                                };

                            var flag = false;

                            // 查询数据库是否有重复记录
                            var context = new DatabaseEntities();
                            var recordList = from r in context.Data_Records
                                             where r.AlarmCount == record.AlarmCount && r.DeviceID == record.DeviceID
                                             select r;

                            if (recordList.Any())
                                flag = true;

                            if (!flag)
                            {
                                if (msg.Exception == (ushort)MsgType.ZGCMD_ANSWER_OK)
                                {
#if _TRACE
                                        Console.WriteLine(string.Format("自动保存丢失记录: 线程Id({0}),发送地址({1}),数据({2}),时间({3})", Thread.CurrentThread.ManagedThreadId, msg.SrcAddr, JsonConvert.SerializeObject(data), DateTime.Now));
#endif
                                    context.AddToData_Records(record);
                                    context.SaveChanges();
                                }
                                else
                                {
                                    if (CheckAlermValue(record))
                                        UpdateDeviceAlermTime(device.DeviceId);

                                    if (null != OnRecordReceived)
                                    {
                                        OnRecordReceived(null, new RecordReceivedEventArgs(record));
                                    }
                                }
                            }
                        }
                        break;
                    #endregion
                }

#if DEBUG
                try
                {
                    var logFolder = AppDomain.CurrentDomain.BaseDirectory + "\\Log\\logrecord";

                    // 创建日志记录文件夹
                    Directory.CreateDirectory(logFolder);

                    #region 修正文件夹路径

                    if (!logFolder.EndsWith("\\"))
                    {
                        logFolder += "\\";
                    }

                    #endregion

                    // 按日期生成文件名
                    var file = logFolder + DateTime.Now.ToShortDateString().Replace('/', '-') + ".txt";

                    var fs = new FileStream(file, FileMode.Append);
                    var sw = new StreamWriter(fs);
                    if (((MsgType)msg.MsgType) == MsgType.ZGCMD_SEND_RECORD)
                    {
                        if (data != null)
                            sw.WriteLine(msg.Exception == (ushort)MsgType.ZGCMD_ANSWER_OK
                                             ? string.Format("历史记录:{0}\r\n数据: {1}\r\nAlertTime:{2}\r\n发生时间:{3}\r\n",
                                                             JsonConvert.SerializeObject(msg),
                                                             JsonConvert.SerializeObject(data), data.AlarmTime,
                                                             DateTime.Now)
                                             : string.Format("记录:{0}\r\n数据: {1}\r\nAlertTime:{2}\r\n发生时间:{3}\r\n",
                                                             JsonConvert.SerializeObject(msg),
                                                             JsonConvert.SerializeObject(data), data.AlarmTime,
                                                             DateTime.Now));
                    }
                    else
                    {
                        sw.WriteLine(string.Format("消息:{0}\r\n发生时间:{1}\r\n", JsonConvert.SerializeObject(msg), DateTime.Now));
                    }
                    sw.Close();
                    fs.Close();
                }
                catch (Exception ex)
                {
                    LogFileHelper.Record(ex);
                }
#endif

                UpdateDeviceOnlineTime(device.DeviceId);
            }
            catch (Exception ex)
            {
                if (data != null)
                    LogFileHelper.Record(ex, string.Format("消息内容:{0}\r\n   数据:{1}\r\n   数据内容:{2}\r\n   AlarmTime:{3}",
                                                           JsonConvert.SerializeObject(msg),
                                                           BitConverter.ToString(msg.Buffer, 0, msg.Buffer.Length),
                                                           JsonConvert.SerializeObject(data),
                                                           data.AlarmTime));
            }
        }

        /// <summary>
        /// 更新设备最后在线时间
        /// </summary>
        /// <param name="deviceId">设备Id</param>
        public void UpdateDeviceOnlineTime(Guid deviceId)
        {
            try
            {
                lock (_deviceOnlineTimeList)
                {
                    if (_deviceOnlineTimeList.ContainsKey(deviceId))
                    {
                        _deviceOnlineTimeList.Remove(deviceId);
                    }
                    _deviceOnlineTimeList.Add(deviceId, DateTime.Now);
                }
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex);
            }
        }

        /// <summary>
        /// 更新设备最后雷击时间
        /// </summary>
        /// <param name="deviceId">设备Id</param>
        public void UpdateDeviceAlermTime(Guid deviceId)
        {
            try
            {
                lock (DeviceAlermTimeList)
                {
                    if (DeviceAlermTimeList.ContainsKey(deviceId))
                    {
                        DeviceAlermTimeList.Remove(deviceId);
                    }
                    DeviceAlermTimeList.Add(deviceId, DateTime.Now);
                }
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex);
            }
        }

        #region 公共方法

        /// <summary>
        /// 监测监听端口是否打开
        /// </summary>
        /// <param name="sender"></param>
        /// <returns></returns>
        public bool CheckPortIsOpen(IWin32Window sender)
        {
            if (!DataRecipient.Instance.IsOpen)
            {
                MessageBox.Show(sender, @"监测端口已断开,请开启后再进行操作!", @"警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }

        /// <summary>
        /// 监测雷电流是否超过告警阀值
        /// </summary>
        /// <param name="record"></param>
        /// <returns></returns>
        public bool CheckAlermValue(Data_Records record)
        {
            if (record.CH1Value != null)
            {
                if (record.CH2Value != null)
                {
                    var maxValue = Math.Max(Math.Abs(record.CH1Value.Value), Math.Abs(record.CH2Value.Value));
                    if (maxValue < DeviceService.Instance.GetAlermValue(record.DeviceID)) return false;
                }
            }

            return true;
        }

        /// <summary>
        /// 更新设备图标界面
        /// </summary>
        /// <param name="control"></param>
        /// <param name="deviceId"></param>
        /// <param name="state"></param>
        public void RefreshPictureBox(Control control, Guid deviceId, DeviceState state)
        {
            try
            {
                var pb = control.Controls.Find(deviceId.ToString(), true).FirstOrDefault() as PictureBox;

                if (null == pb) return;
                switch (state)
                {
                    case DeviceState.Offline:
                        {
                            pb.Image = Resources.offline;
                            pb.BackColor = Color.Transparent;
                            pb.Enabled = false;
                        }
                        break;
                    case DeviceState.Online:
                        {
                            pb.Image = null;
                            pb.BackColor = Color.DarkCyan;
                            pb.Enabled = true;
                        }
                        break;
                    case DeviceState.Alarm:
                        {
                            pb.Image = Resources.light__2_;
                            pb.BackColor = Color.DarkCyan;
                            pb.Enabled = true;
                        }
                        break;
                }
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex);
            }
        }

        public void RefreshValue(Guid deviceId, Panel panel, Dictionary<Guid, List<Data_Records>> dataList, bool isPer)
        {
            try
            {
                List<Data_Records> records;
                dataList.TryGetValue(deviceId, out records);

                if (null == records) records = new List<Data_Records>();

                if (isPer)
                {
                    var lbA = panel.Controls.Find("lbA" + panel.Tag, false).FirstOrDefault() as Label;
                    if (null != lbA) lbA.Text = (records.Select(r => r.CH1Value).OrderByDescending(x => x != null ? Math.Abs(x.Value) : 0).Take(1).FirstOrDefault() ?? (decimal)0.000).ToString("f3") + @" kA";

                    var lbB = panel.Controls.Find("lbB" + panel.Tag, false).FirstOrDefault() as Label;
                    if (null != lbB) lbB.Text = (records.Select(r => r.CH2Value).OrderByDescending(x => x != null ? Math.Abs(x.Value) : 0).Take(1).FirstOrDefault() ?? (decimal)0.000).ToString("f3") + @" kA";
                }
                else
                {
                    var lb = panel.Controls.Find("lb" + panel.Tag, false).FirstOrDefault() as Label;
                    if (null != lb)
                    {
                        var valueA = records.Select(r => r.CH1Value).OrderByDescending(x => x != null ? Math.Abs(x.Value) : 0).Take(1).FirstOrDefault() ?? (decimal)0.000;
                        var valueB = records.Select(r => r.CH2Value).OrderByDescending(x => x != null ? Math.Abs(x.Value) : 0).Take(1).FirstOrDefault() ?? (decimal)0.000;

                        if (Math.Abs(valueB) > Math.Abs(valueA))
                            valueA = valueB;
                        lb.Text = valueA.ToString("f3") + @" kA";
                    }
                }
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex);
            }
        }

        public void RefreshValue(Guid deviceId, Panel panel, Dictionary<int, List<Data_Records>> dataList)
        {
            try
            {
                if (null == panel) return;

                List<Data_Records> records = null;

                var device = DeviceService.Instance.GetDevice(deviceId);
                if (device != null) dataList.TryGetValue(device.Position.Value, out records);

                if (null == records) records = new List<Data_Records>();
                var lb = panel.Controls.Find("lb" + panel.Tag, false).FirstOrDefault() as Label;
                if (null != lb)
                {
                    var valueA = records.Select(r => r.CH1Value).OrderByDescending(x => x != null ? Math.Abs(x.Value) : 0).Take(1).FirstOrDefault() ?? (decimal)0.000;
                    var valueB = records.Select(r => r.CH2Value).OrderByDescending(x => x != null ? Math.Abs(x.Value) : 0).Take(1).FirstOrDefault() ?? (decimal)0.000;

                    if (Math.Abs(valueB) > Math.Abs(valueA))
                        valueA = valueB;
                    lb.Text = valueA.ToString("f3") + @" kA";
                }

                var lbB = panel.Controls.Find("lbB" + panel.Tag, false).FirstOrDefault() as Label;
                if (null != lbB) lbB.Text = (records.Select(r => r.CH2Value).Max() ?? (decimal)0.000).ToString("f3") + @" kA";
            }
            catch (Exception ex)
            {
                LogFileHelper.Record(ex);
            }
        }

        public void pb_MouseLeave(object sender, EventArgs e)
        {
            var pb = (PictureBox)sender;
            pb.BackColor = Color.DarkCyan;
        }

        public void pb_MouseEnter(object sender, EventArgs e)
        {
            var pb = (PictureBox)sender;
            pb.BackColor = Color.DarkGray;
        }

        #endregion

        public void SetErrorInfo(string text, ref bool remove)
        {
            _form.btnErrLog.ForeColor = Color.Red;

            if (remove)
            {
                ErrorInfoList.Clear();
                remove = false;
            }

            ErrorInfoList.Add(new ErrInfoItem { Info = text, Time = DateTime.Now });
        }

        static MainConsole _instance;
        /// <summary>
        /// 单例
        /// </summary>
        public static MainConsole Instance
        {
            get
            {
                lock (ObjLock)
                {
                    return _instance ?? (_instance = new MainConsole());
                }
            }
        }
    }
}
